home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1994 December
/
PSL Monthly Shareware CD-ROM (Public Software Library)(December 1994).bin
/
prgmming
/
dos
/
asm
/
interupt.mac
< prev
next >
Wrap
Text File
|
1984-08-27
|
4KB
|
213 lines
;MACROS for items that replace BIOS calls
;
; Prolog Segname
; start of code should be labeled
; ENTRY:
;
; Epilog IntNo,Pointr,SegName
; IntNo is interrupt number
; Pointr is name of data area DD
;
; Finish SegName,StackSize
; the variable zzarg gets set to the first word (two chars) entered
; on the command line
;
; Finish has first label of CONFIG:
; if HIMSG exists it is printed (put after Epilog)
; eg jmp CONFIG
; HIMSG db 'hello$'
; Prolog SegName
; This pushes a bit and then runs to the rest
; name the segment here
Prolog MACRO SegName
pBase equ 00h ;pBase of memory (seg)
zbufr equ 5Dh
DGROUP GROUP SegName,ZzUseStk
SegName Segment para
Moveit PROC FAR
ASSUME CS:SegName
;Set up the stack so a RET instruction
; will jump to the
; beginning of program segment
push ds ;Prog segment
xor ax,ax
push ax ;Offset
jmp DoTheRest
db '1982 MSZachmann'
MoveIt endp
ENDM
; Epliog IntNo,Pointr
;
; This does the work of checking
; that no other one has been loaded.
; Just exits if other loaded. IntNo
; is the interrupt number
; Pointer is a pointer to where the
; old address should be stored.
Epilog MACRO IntNo,Pointr,SegName
EndEntry label near
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;
; Temporary stuff
;
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Initial proc near
DoTheRest LABEL NEAR
;Check to see if already loaded.
; if so, exit
;
mov BX,zbufr
mov AX,[BX]
mov CS:zzarg,AX
push DS
mov AX,pBase
mov DS,AX
mov BX,4*IntNo
LES SI,dword ptr [BX]
;now have start address of code
mov SI,offset ENTRY ;start here
mov DI,SI
mov AX,CS
mov DS,AX ; all set for compare
CLD ;forward
mov CX,010 ;should suffice
REPE CMPSW
pop DS
; now set status byte to 0FFFh
mov AX,0FFFFh
push AX
jne short Nxt1
jmp Config
;Modify the INT 20H instruction at DS:1
; Make it an INT 27h
Nxt1: mov BX,1
mov BYTE PTR [BX],27h
;relocate down a page using CS:->DS:
;
mov AX,DS
mov ES,AX ;set ES to page lower
mov AX,CS
mov DS,AX ;set DS to here
mov SI,offset ENTRY
mov DI,SI ;both same
mov CX,offset EndEntry-offset ENTRY
shr CX,1 ;div by 2 for wds
inc CX ;for luck
lz1: rep movsw
and CX,CX
jnz lz1
;Set DS:BX to point to int vector IntNo
; (Pointr i/o )
MOV AX,pBase
MOV DS,AX
MOV BX,4*IntNo
push ES ;save new page
;Set ES:DI to old vector 10h
LES DI,DWORD PTR [BX]
;Reset the vector to Entry point
MOV WORD PTR [BX],offset ENTRY
pop CX ;new page number
MOV WORD PTR [BX+2],CX
;Now put the old vector address
; into the call pointer at
; DS:Pointr
ASSUME DS:&SegName
;actually DS is SegName-100h
MOV DS,CX
MOV Pointr,DI
MOV Pointr+2,ES
;set status to NEW
pop AX ;get status back
xor AX,AX
push AX ;for later
Initial endp
ENDM
; Finish
; exits
; takes segment name and stack size
Finish MACRO SegName,SSizez
;Set up DX to the program size, note
; that CS is 100h larger than
; program prefix segment
; ! This is the lazy way, and
; assumes PC-DOS stays consistent.
Nconfig proc far
CONFIG label near
mov AX,CS
mov DS,AX ;for print screen
IFDEF HIMSG
mov AH,9 ;print string
mov DX,offset CLearstr
int 21h ;DOS
mov DX,offset HIMSG
int 21h
ENDIF
pop AX ;get status
and AX,AX ;if zero then new
jz CONF3
mov DX,offset AlThere
mov AH,9
int 21h ;print
CONF3: MOV DX,offset endENTRY
RET ;Exit from the system
;By doing an INT 27h
ALThere db '*** This program was already loaded. ***',13,10,'$'
zzarg dw ? ;will contain first word at 80h
Clearstr db 13
db 27 dup(10)
db '$'
Nconfig endp
SegName ends
; ensure that stack gets loaded highest in memory
; by naming it large (ZZ...)
ZzUSERST segment STACK
dw SSizez dup (?)
ZzUSERST ENDS
ENDM
RST ENDS
ENDM